package com.tom.architect02.ui20.day14;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.FrameLayout;

import androidx.core.view.ViewCompat;
import androidx.customview.widget.ViewDragHelper;

/**
 * Added by Tom on 2024/06/13.
 */
public class VerticalDragListView extends FrameLayout {
    private ViewDragHelper mDragHelper;     // 可以认为这是系统给我们写好的一个工具类
    private View mDragListView;
    private int mMenuHeight; // 菜单的高度
    private boolean mMenuIsOpen = false; // 菜单是否打开

    public VerticalDragListView(Context context) {
        this(context, null);
    }

    public VerticalDragListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerticalDragListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDragHelper = ViewDragHelper.create(this, mDragHelperCallback);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();
        if (childCount != 2) {
            throw new RuntimeException("VerticalDragListView 只能存放2个 childView!!");
        }
        mDragListView = getChildAt(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        View menuView = getChildAt(0);
        mMenuHeight = menuView.getMeasuredHeight();
    }
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
//        if (changed){
//            View menuView = getChildAt(0);
//            mMenuHeight = menuView.getMeasuredHeight();
//        }
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    // ListView可以滑动，但是菜单不可见了。
    // 让父类不拦截子控件 的触摸事件：getParent().requestDisallowInterceptTouchEvent(true);
    // 改变的其实就是 mGroupFlags的值。
    private float mDownY;
//    AbsListView.onTouch() down事件会返回true，拦截事件，导致VDLV onTouch 拿不到Down事件。
    // VDLV.onInterceptTouchEvent().DOWN --> ListView.onTouch()直接消费了down事件-- >
    // VDLV.onInterceptTouchEvent().MOVE --> VDLV.onTouchEvent().MOVE

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mMenuIsOpen) {
            return true; // 菜单已打开，要全部拦截。VDLV自己处理。
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownY = ev.getY();
                mDragHelper.processTouchEvent(ev); // 让DragHelper拿到完整的事件。
                break;
            case MotionEvent.ACTION_MOVE:
                float moveY = ev.getY();
                if (moveY - mDownY > 0 && !canChildScrollUp()) {
                    // 向下滑动 且 滚动到了顶部(不能向上滚)， 拦截
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDragHelper.processTouchEvent(event); // 处理触摸事件
        return true;
    }

    /**
     * @return Whether it is possible for the child view of this layout to
     * scroll up. Override this if the child view is a custom view.
     * 判断View是否滚动到了最顶部,还能不能向上滚
     */
    public boolean canChildScrollUp() {
        if (android.os.Build.VERSION.SDK_INT < 14) {
            if (mDragListView instanceof AbsListView) {
                final AbsListView absListView = (AbsListView) mDragListView;
                return absListView.getChildCount() > 0
                        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                        .getTop() < absListView.getPaddingTop());
            } else {
                return ViewCompat.canScrollVertically(mDragListView, -1) || mDragListView.getScrollY() > 0;
            }
        } else {
            return ViewCompat.canScrollVertically(mDragListView, -1);
        }
    }

    private ViewDragHelper.Callback mDragHelperCallback = new ViewDragHelper.Callback() {
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            // 指定那个child view 可以拖动, 菜单部分不可拖动。
            return child == mDragListView; // 只能拖动listView
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            if (top <= 0) top = 0;
            if (top >= mMenuHeight) top = mMenuHeight;
            return top; // 垂直拖动移动的位置。
        }

        // 松开手指
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
//            Log.e("tag", "y:" + yvel + " height:" + mMenuHeight);
//            Log.e("tag", "top:" + mDragListView.getTop());
            if (releasedChild != mDragListView) return;
            if (mDragListView.getTop() >= (mMenuHeight / 2)) {
                // 打开
                mDragHelper.settleCapturedViewAt(0, mMenuHeight);
                mMenuIsOpen = true;
            } else { // 滚动到0的位置：关闭
                mDragHelper.settleCapturedViewAt(0, 0);
                mMenuIsOpen = false;
            }
            invalidate();
        }
    };

    @Override
    public void computeScroll() {
        // 响应滚动
        if (mDragHelper.continueSettling(true)) {
            invalidate();
        }
    }
}
